import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;
import java.net.UnknownHostException;

public class Agent extends Thread {
	
	private static String host = "127.0.0.1";
	private static int port = 10000;
	private static Communication com;
	private static int id = 0;
	
	public static void main (String args[])  throws UnknownHostException, IOException, InterruptedException {
		
		//DEPLOIEMENT DE LA SOCKET RECEPTION DU MANAGER
		System.out.println("Deploying manager's communications...");
		//start();
		System.out.println("##########################");
		
		//INITIALISATION DES ACTEURS, SANS PARAMS
		ActorFactory factory = new ActorFactory();
		Actor obj = factory.createActor("DefaultActor");
		System.out.println("actor #1 ("+ obj.getHost() +":"+ obj.getPort() +")");
		System.out.println("##########################");

		//ENVOI DES MSGS AUX ACTEURS
		Message msg;
		
		System.out.println("\n~~ Manager sending msg...");
		msg = new Message(id, "msg_agentInfo", new String[]{host, String.valueOf(port)});
		SendMsg(obj.getHost(), obj.getPort(), msg);
		Thread.sleep(1000);
		
		System.out.println("\n~~ Manager sending msg...");
		msg = new Message(id, "msg_dummy", new String[]{"Dummy message, test !"});
		SendMsg(obj.getHost(), obj.getPort(), msg);
		Thread.sleep(1000);
		
		System.out.println("\n~~ Manager sending msg...");
		msg = new Message(id, "msg_action", new String[]{"2", "5", "toto" });
		SendMsg(obj.getHost(), obj.getPort(), msg);
		Thread.sleep(1000);
		
		System.out.println("\n~~ Manager sending msg...");
		msg = new Message(id, "msg_kill", new String[]{"Halt"});
		SendMsg(obj.getHost(), obj.getPort(), msg);
	}
	
	public void run(){
		com = new Communication(host, port);
		com.deploy();
	}
	
	
	private static void SendMsg(String host, int port, Message msg) throws UnknownHostException, IOException{
		Socket socket = new Socket(host, port);
		OutputStream os = socket.getOutputStream(); 
		ObjectOutputStream oos = new ObjectOutputStream(os); 
		oos.writeObject(msg); 
		oos.close();  
		os.close();  
		socket.close();
	}
}

class ActorFactory {
	
	private String host = "127.0.0.1";
	private int port = 34567;
	private int nbActor = 0;
	private String method_name = "commencer";
	
	public Actor createActor(String type){
		System.out.println("Creating actor:"+type);
			try {
				Class cl = Class.forName(type);
				Object o = cl.newInstance();
				Class[] types = new Class[] {String.class, String.class, String.class};
				Constructor ct = cl.getConstructor(types);
				Object obj = ct.newInstance(new String[]{this.host, String.valueOf(this.port), String.valueOf(this.nbActor)} );
				Method m = cl.getMethod(method_name, null);
				m.invoke(obj, null);
				return (Actor) obj;
			} 
			catch (ClassNotFoundException e) { e.printStackTrace();	} 
			catch (InstantiationException e) { e.printStackTrace();	} 
			catch (IllegalAccessException e) { e.printStackTrace();	} 
			catch (SecurityException e) { e.printStackTrace(); } 
			catch (NoSuchMethodException e) { e.printStackTrace(); } 
			catch (IllegalArgumentException e) { e.printStackTrace(); } 
			catch (InvocationTargetException e) { e.printStackTrace(); }
			return null;
	}
	
}



	
